perm filename SAMPLE.DOC[TEX,DEK] blob sn#427769 filedate 1979-03-28 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00009 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	{{\head{Introduction} \titlepage \runninglefthead{EXAMPLE OF TEXDOC}\setcount0 1
C00007 00003	{{ Here are samples of integer definitions that will cause {\:c UNDOC} to make
C00011 00004	{{\head{Data structures}
C00014 00005	{{\head{Input}
C00018 00006	{ Input from external file, 
C00021 00007	{ Scan a control ... } =
C00024 00008	{ Move to next line of file, or
C00032 00009	{ Input from token list, \goto\ \\{do_get_next} if end of list 
C00039 ENDMK
C⊗;
{{\head{Introduction} \titlepage \runninglefthead{EXAMPLE OF TEXDOC}\setcount0 1
This is a sample ``style sheet'' to illustrate the recommended conventions
desirable for \TEX\ documentation. Explanatory material that has been enclosed
in $\{\{$ and $\}\}$ (like the explanatory material you are now reading)
should be acceptable \TEX\ input; it will be removed from the corresponding
{\:c PASCAL} program produced by {\:c UNDOC}, but it will be typeset in place as
part of the printed documentation produced by {\:c TEXDOC}.

Documentation files like this one have the suffix \.{.DOC}; the {\:c UNDOC} program
converts them into files with suffix \.{.PAS}, and the {\:c TEXDOC} program converts
them into files with suffix \.{.TEX}.

The program segment below is the \\{get_next} procedure, recoded from page 10 of
the original {\:c SAIL} version in file \.{TEXSYN.SAI}. The program conventions have
changed slightly, mainly because \\{inbuf} and \\{curbuf} now are simply
pointers to an ascii array \\{instack}, not variables of type {\bf string}.
Some of the names have changed too; for example, \\{align_insert} has been
substituted for the less appropriate name \\{aligndelim}. The variable
\\{page_warning} is now of type (\\{OK}, \\{def_of}, \\{use_of}). And so on.}}
{{ Here are samples of integer definitions that will cause {\:c UNDOC} to make
corresponding substitutions in the program text:}}
{ escape } := 0		{{ escape delimiter (\.{\\} in \TEX\ manual) }}
{ lbrace } := 1		{{ begin block symbol ( \.{\char'173} ) }}
{ rbrace } := 2		{{ end block symbol ( \.{\char'176} ) }}
{ mathbr } := 3		{{ math break (  \.{\char'44} ) }}
{ tabmrk } := 4		{{ tab mark ( \.{\char'26} ) }}
{ carret } := 5		{{ carriage return or comment ( \.{\char'45} ), \.{\\cr} }}
{ macprm } := 6		{{ macro parameter ( \.{\char'43} ) }}
{ supmrk } := 7		{{ superscript ( \.{\char'136} ) }}
{ submrk } := 8		{{ subscript ( \.{\char'175} ) }}
{ ignore } := 9		{{ characters to ignore }}
{ spacer } := 10	{{ characters treated as blank space }}
{ letter } := 11	{{ characters treated as letters }}
{ otherchar } := 12	{{ none of the above character types }}
{ parend } := 13	{{ end of paragraph }}
{ match } := 14		{{ macro parameter matching }}
{ charcodes } := 13	{{ number of distinct character types }}
{ tokenlist } := 0	{{ scanning a token list }}
{ midline } := 1	{{ scanning a line of characters }}
{ skipblanks } := midline+charcodes	{{ like \\{midline} but ignoring blanks }}
{ newline } := skipblanks+charcodes	{{ beginning a new line of characters }}
{ line_feed } := '12	{{ end of line in ascii input file }}
{ form_feed } := '14	{{ end of page in ascii input file }}
{ carriage_return } := '15	{{ precedes end of line in ascii input file }}
{ hashsize } := 353	{{ hashtable size, must be prime and less than
	$\\{charsize}-127$ }}
{ texpars } := 10 {{ number of distinct parameters settable by \.{\\chpar} }}
{ eqtbsize } := hashsize+128+128+texpars  {{ size of table for current values }}
{ chartype_offset } := hashsize+128 {{ location of character type in \\{eqtb} }}
{ tracing_offset } := hashsize+268 {{ location of tracing control in \\{eqtb} }}

{ param } := 0	{{ \\{recovery} code for parameters }}
{ ujlist } := 1	{{ \\{recovery} code for $u↓j$ lists in alignments }}
{ vjlist } := 2	{{ \\{recovery} code for $v↓j$ lists in alignments }}
{ inserted } := 3 {{ \\{recovery} code for an inserted token list }}

{ do_get_next } := 1 {{ label in \\{get_next} procedure }}
{ end_get_next } := 2 {{ label in \\{get_next} procedure }}
{ inner_switch } := 3 {{ label in \\{get_next} procedure }}
{{\head{Data structures}
It isn't clear exactly what types should be declared, but the tentative
types listed below appear in this example. The roles of \\{loc} and \\{recovery}
have been reversed for character files, so that \\{loc} is always of type
\\{integer} and \\{recovery} is always of type \\{inflnk}. The \\{info} field
of \\{recovery} is now set to positive values in all cases, instead of using
conventions like $-l$, etc.}}
type inflnk = packed record info: 0..131071; link: 0..32767 end;
token = packed record cmd: 0..15; chr: 0..1023 end;
toklnk = packed record tok: token; link: 0..32767 end;
eqtbval = packed record idcmd: 0..127; idlev: 0..31; idlen: 0..7;
	link: 0..32767 end;
tracebits = packed record mmm:0..511; nnn: 0..511; ddtflag: 0..1; inputflag: 0..1;
	replflag: 0..1; dumpflag: 0..1; detailflag: 0..1; overflag: 0..1 end;
ee = record case 1..4 of
	1: (eq: eqtbval);
	2: (int: integer);
	3: (pts: real);
	4: (tr: tracebits)
	end;
mm = record case 1..5 of
	1: (pts: real);
	2: (int: integer);
	3: (il: inflnk);
	4: (tl: toklnk);
	5: (something_else_probably_too)
	end;
var mem = array 0..memsize-1 of mm;
eqtb = array 0..eqtbsize-1 of ee;

{{Here's an example of a macro with a parameter:}}
{ chartype } #= eqtb[#+chartype_offset].int
{{\head{Input}
The \\{get_next} procedure acts as \TEX's eyes and mouth, as they read and
gobble up source files or stored tokens. The main duty of \\{get_next} is to
input one token, setting \\{curcmd} to the code for the corresponding command
and setting \\{curchar} to the code for the corresponding character. Furthermore,
the value of \\{hashentry} is made nonnegative if and only if the new input token
is a control sequence (and, if so, \\{hashentry} is set to the corresponding
location in \\{eqtb}). Although this procedure has to handle a lot of different
cases, an attempt has been made to keep its inner loop reasonably short and fast.}}
procedure get_next; {{ sends next input token to \\{curcmd} and \\{curchar} }}
label do_get_next, {{ go here to get the next token }}
end_get_next, {{ go here when the next token has been got }}
inner_switch; {{ go here to read the next character }}
var { Locals for \\{get_next} }
begin
do_get_next:
if state <> tokenlist then {{ Reading from an external file }}
	{ Input from external file, 
		  \goto\ \\{end_get_next} with paragraph end token if end of file,
		  \goto\ \\{do_get_next} if no input token found }
else	{ Input from token list, \goto\ \\{do_get_next} if end of list 
				or if a parameter needs to be expanded };
if { End of alignment entry sensed? } then
	{ Insert the $\langle v↓j \rangle$ list and \goto\ \\{do_get_next} };
end_get_next:
end

{ End of align ... } = alignstate = 0  and ((curcmd=tabmrk) or (curcmd=carret))

{ Insert the $\lan ... } = 
begin align_insert;
hashentry := -1; {{ this resets \\{hashentry} in case it points to \.{\\cr} }}
goto do_get_next
end
{ Input from external file, 
	\goto\ \\{end_get_next} with paragraph end token if end of file,
	\goto\ \\{do_get_next} if no input token found } =
if curbuf < instack_ptr then {{ Current line not empty }}
	begin { Read one character of the input };
	{ Change state if necessary, and \goto\ \\{inner_switch} if the
		current character should be ignored }
	end
else	begin { Move to next line of file, or
		\goto\ \\{end_get_next} with paragraph end token if end of file,
		or \goto\ \\{do_get_next} if inserted list just ended };
		goto inner_switch
	end

{ Read one char ... } = 
begin curchar := ord(instack[instack_ptr]);
instack_ptr := instack_ptr + 1;
curcmd := chartype(curchar)
end

{ Change state ... } = 
case state + curcmd of
{ Cases where character is ignored }: goto inner_switch;
{ Cases involving an escape character }: { Scan a control sequence };
{ Handle situations involving spaces, braces, changes of state};
others: { Do nothing }
end

{ Cases where character is ignored } = midline+ignore, skipblanks+ignore,
			skipblanks+spacer, newline+ignore, newline+spacer

{ Cases involving an escape character } = midline+escape, skipblanks+escape,
			newline+escape

{ Do nothing } =
{ Scan a control ... } =
begin control_seq;
with eqtb[hashentry].eq do
	begin curcmd := idcmd; curchar := link
	end;
state := skipblanks
end

{ Handle situations inv... } =
midline+spacer: { Set \\{skipblanks} state and emit a space };
midline+carret: { Set \\{newline} state and emit a space };
skipblanks+carret: { Set \\{newline} state and \goto\ \\{inner_switch} };
midline+lbrace: alignstate := alignstate + 1;
skipblanks+lbrace, newline+lbrace: { Set \\{midline} state and
	increase \\{alignstate} };
midline+rbrace: alignstate := alignstate -1;
skipblanks+rbrace, newline+rbrace: { Set \\{midline} state and
	decrease \\{alignstate} };
{ Situations leading to \\{midline} state }: state := midline

{ Set \\{skipblanks} state ... } =
begin state := skipblanks;
curchar := ord(' ')
end

{ Set \\{newline} state and emit ... } =
begin state := newline;
curbuf := instack_ptr; {{ empty the buffer }}
curcmd := spacer;
curchar := ord(' ')
end

{ Set \\{newline} state and \go... } =
begin state := newline;
curbuf := instack_ptr; {{ empty the buffer }}
goto inner_switch
end

{ Situations leading to \\{midline} ... } = skipblanks+mathbr, skipblanks+tabmrk,
	skipblanks+macprm, skipblanks+supmrk, skipblanks+submrk, skipblanks+letter,
	skipblanks+otherchar, newline+mathbr, newline+tabmrk, newline+macprm,
	newline+letter, newline+otherchar

{ Set \\{midline} state and in... } =
begin state := midline;
alignstate := alignstate + 1
end

{ Set \\{midline} state and de... } =
begin state := midline;
alignstate := alignstate - 1
end
{ Move to next line of file, or
	  \goto\ \\{end_get_next} with paragraph end token if end of file,
	  or \goto\ \\{do_get_next} if inserted list just ended } =
begin if filename <> 0 then {{ Reading from a character file }}
	{ Read next line into input buffer }
else if inptr <> 0 then {{ Input was text inserted by user during error recovery }}
	begin popinput; {{ Restore previous input source }}
	goto do_get_next
	end
else { Input online from terminal into input buffer };
curbuf := inbuf {{ Prepare to scan input buffer }}
end

{ Read next line ... } =
begin inputln; {{ Read current file up to line feed or form feed or eof }}
if eoff then { Process end of file and \goto\ \\{end_get_next} with \\{parend} };
{ Trace the input line if requested };
{ Advance line and page number }
end

{ Process end of file and ... } =
begin write(')'); {{ Show user that the file has been read }}
release(loc); {{ Close the file }}
{ Check if end of page is {\:c OK} };
popinput; {{ Restore previous status }}
curcmd := parend; curchar := 0;
goto end_get_next
end

{ Check if end of page is... } =
if page_warning <> OK then page_end_error

{ Trace the input line if requested } =
if eqtb[trace_offset].tr.inputflag then
	begin println;
	for curbuf := inbuf to instack_ptr-1 do write(instack[curbuf]);
	{ Input online ... };
	end

{ Input online ... } = 
begin println; print('*'); {{ prompt the user }}
inputln;
{ Echo the input on the output file };
{ Define the escape character if the first character has just been read };
end

{ Echo ... } = for curbuf := inbuf to instack_ptr-1 do write(instack[curbuf])

{ Define the escape ... } =
if (escapechar<0) and (ord(instack[inbuf])<>carriage_return) then
	begin escapechar := ord(instack[inbuf]);
	chartype(escapechar) := escape;
	end

{ Advance line and page number } =
with recovery do
	if brchar = form_feed then {{ End of page }}
		begin info := info + 1; {{ advance page number }}
		print(' '); print(info); {{ print progress report for user }}
		link := 0; {{ set line number zero }}
		{ Check if end of page is ... }
		end
	else link := link + 1 {{ advance line number }}
{ Input from token list, \goto\ \\{do_get_next} if end of list 
				or if a parameter needs to be expanded } =
if loc <> 0 then {{ Current token list is not empty }}
	begin { Read next token from token list};
	case curcmd of 
		0 :{ Process a control sequence token };
		outpar : { Insert a macro parameter and \goto\ \\{do_get_next} };
		lbrace : alignstate := alignstate + 1;
		rbrace : alignstate := alignstate - 1;
		others: { Do nothing }
		end
	end
else	begin { Process end of token list };
	popinput; {{ Return to previous level of input }}
	goto do_get_next
	end

{ Locals for \\{get_next} } +=
t: token; {{ packed token stored in a token list }}
tt: toklnk; {{ packed token and link stored in a token list }}

{ Read next token ... } =
begin tt := mem[loc].tl;
with tt do
	begin t := tok; {{ get token to emit }}
	loc := link; {{ advance to next element of token list }}
	curchar := t.chr;
	curcmd := t.cmd;
	end
end

{ Process a control ... } =
begin hashentry := curchar;
with eqtb[curchar].eq do
	begin curcmd := idcmd; curchar := link
	end
end

{ Insert a macro par... } =
begin pushinput; {{ Begin a new level of input }}
with recovery do
	begin loc := parstack[link + curchar]; {{ Beginning of the parameter }}
	info := param;
	link := loc; {{ \\{recovery} convention for parameter token list }}
	goto do_get_next {{ The state remains equal to \\{tokenlist} }}
	end
end

{ Process end of token list } =
case recovery.info of
param, vjlist: { Do nothing };
ujlist: alignstate := 0; {{ $u↓j$ list of an alignment has just ended }}
inserted: dslist(recovery); {{ Destroy a temporarily inserted list }}
others: { Process end of macro body }
end

{ Process end of macro body } =
with recovery do
	begin delrclink(info); {{ Dereference the macro body }}
	while parptr>link do
		begin parptr := parptr-1;
		dslist(parstack[parptr]) {{ Destroy each parameter }}
		end
	end